package com.atguign.gulimall.product.service.impl;

import com.atguign.gulimall.product.dao.*;
import com.atguign.gulimall.product.entity.*;
import com.atguign.gulimall.product.feign.CouponFeifnService;
import com.atguign.gulimall.product.feign.SearchFenifnService;
import com.atguign.gulimall.product.feign.WareFeifnService;
import com.atguign.gulimall.product.service.*;
import com.atguign.gulimall.product.vo.*;
import com.atguigu.common.constant.ProductConstant;
import com.atguigu.common.to.MemberPriceTo;
import com.atguigu.common.to.SkuReductionTo;
import com.atguigu.common.to.SpuBoundsTo;
import com.atguigu.common.to.es.SkuEsmodel;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;
import com.atguigu.common.utils.R;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;


@Service("spuInfoService")
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    @Autowired
    private SpuInfoDescService spuInfoDescService;
    @Autowired
    private SpuImagesService spuImagesService;
    @Autowired
    private ProductAttrValueService productAttrValueService;
    @Autowired
    private SkuInfoDao skuInfoDao;
    @Autowired
    private SkuImagesService skuImagesService;
    @Autowired
    private SkuSaleAttrValueService skuSaleAttrValueService;
    @Autowired
    private AttrDao attrDao;
    @Autowired
    private CouponFeifnService couponFeifnService;
    @Autowired
    private BrandDao brandDao;
    @Autowired
    private CategoryDao categoryDao;
    @Autowired
    private WareFeifnService wareFeifnService;
    @Autowired
    private SearchFenifnService searchFenifnService;
    @Autowired
    private SpuInfoDao spuInfoDao;
    @Autowired
    private SkuInfoServiceImpl skuInfoService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                new QueryWrapper<SpuInfoEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 保存整个商品数据
     *
     * @param vo
     */
    @GlobalTransactional
    @Transactional
    @Override
    public void saveSpuInfo(SpuSaveVo vo) {
        //保存spu基本信息
        SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
        BeanUtils.copyProperties(vo, spuInfoEntity);
        spuInfoEntity.setCreateTime(new Date());
        spuInfoEntity.setUpdateTime(new Date());
        this.saveBaseSpuInfo(spuInfoEntity);
        //保存spu图片
        List<String> decript = vo.getDecript();
        SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
        spuInfoDescEntity.setSpuId(spuInfoEntity.getId());
        spuInfoDescEntity.setDecript(String.join(",", decript));
        spuInfoDescService.save(spuInfoDescEntity);
        //保存图集
        List<String> images = vo.getImages();
        if (images != null && !images.isEmpty()) {
            List<SpuImagesEntity> collect = images.stream().map(image -> {
                SpuImagesEntity spuImagesEntity = new SpuImagesEntity();
                spuImagesEntity.setSpuId(spuInfoEntity.getId());
                spuImagesEntity.setImgUrl(image);
                return spuImagesEntity;
            }).filter(image -> StringUtils.hasText(image.getImgUrl())).collect(Collectors.toList());
            spuImagesService.saveBatch(collect);
        }

        //保存attr参数
        List<BaseAttrs> baseAttrs = vo.getBaseAttrs();
        List<ProductAttrValueEntity> productAttrValueEntities = baseAttrs.stream().map(attrs -> {
            ProductAttrValueEntity productAttrValueEntity = new ProductAttrValueEntity();
            productAttrValueEntity.setAttrId(attrs.getAttrId());
            AttrEntity attrEntity = attrDao.selectById(attrs.getAttrId());
            productAttrValueEntity.setAttrName(attrEntity.getAttrName());
            productAttrValueEntity.setQuickShow(attrs.getShowDesc());
            productAttrValueEntity.setSpuId(spuInfoEntity.getId());
            productAttrValueEntity.setAttrValue(attrs.getAttrValues());
            return productAttrValueEntity;
        }).filter(attrs -> StringUtils.hasText(attrs.getAttrValue())).collect(Collectors.toList());
        productAttrValueService.saveBatch(productAttrValueEntities);
        //spu远程保存spu积分信息
        SpuBoundsTo spuBoundsPo = new SpuBoundsTo();
        Bounds bounds = vo.getBounds();
        BeanUtils.copyProperties(bounds, spuBoundsPo);
        spuBoundsPo.setSpuId(spuInfoEntity.getId());
        R r = couponFeifnService.saveSpuBounds(spuBoundsPo);
        if (r.getCode() != 0) {
            log.error("远程保存spu积分信息失败");
        }

        //sku
        List<Skus> skus = vo.getSkus();
        if (skus != null && !skus.isEmpty()) {
            for (Skus sku : skus) {
                //sku基本信息
                SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
                BeanUtils.copyProperties(sku, skuInfoEntity);
                skuInfoEntity.setBrandId(spuInfoEntity.getBrandId());
                skuInfoEntity.setCatalogId(spuInfoEntity.getCatalogId());
                skuInfoEntity.setSaleCount(0L);
                skuInfoEntity.setSpuId(spuInfoEntity.getId());
                skuInfoEntity.setSkuDefaultImg("");
                sku.getImages().forEach(img -> {
                    if (img.getDefaultImg() == 1)
                        skuInfoEntity.setSkuDefaultImg(img.getImgUrl());
                });
                skuInfoDao.insert(skuInfoEntity);

                //sku图片信息
                List<SkuImagesEntity> collect = sku.getImages().stream().map(img -> {
                            SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
                            skuImagesEntity.setImgUrl(img.getImgUrl());
                            skuImagesEntity.setDefaultImg(img.getDefaultImg());
                            skuImagesEntity.setSkuId(skuInfoEntity.getSkuId());
                            return skuImagesEntity;
                        }).filter(skuImagesEntity -> StringUtils.hasText(skuImagesEntity.getImgUrl()))
                        .collect(Collectors.toList());
                skuImagesService.saveBatch(collect);
                //sku销售属性
                List<Attr> attr = sku.getAttr();
                List<SkuSaleAttrValueEntity> collect1 = attr.stream().map(attrs -> {
                    SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
                    BeanUtils.copyProperties(attrs, skuSaleAttrValueEntity);
                    skuSaleAttrValueEntity.setSkuId(skuInfoEntity.getSkuId());
                    skuSaleAttrValueEntity.setAttrSort(0);
                    return skuSaleAttrValueEntity;
                }).filter(attrs -> StringUtils.hasText(attrs.getAttrValue())).collect(Collectors.toList());
                skuSaleAttrValueService.saveBatch(collect1);

                //远程保存sku优惠信息
                SkuReductionTo skuReductionTo = new SkuReductionTo();
                BeanUtils.copyProperties(sku, skuReductionTo);
                skuReductionTo.setSkuId(skuInfoEntity.getSkuId());
                List<MemberPriceTo> collect2 = sku.getMemberPrice().stream().map(item -> {
                    MemberPriceTo memberPriceTo = new MemberPriceTo();
                    BeanUtils.copyProperties(item, memberPriceTo);
                    return memberPriceTo;
                }).collect(Collectors.toList());
                skuReductionTo.setMemberPrice(collect2);
                R r1 = couponFeifnService.saveSkuReduction(skuReductionTo);
                if (r1.getCode() != 0) {
                    log.error("远程保存sku优惠信息失败");
                }
            }
        }


    }

    /**
     * 保存spu基本属性
     *
     * @param spuInfoEntity
     */

    @Override
    public void saveBaseSpuInfo(SpuInfoEntity spuInfoEntity) {
        this.baseMapper.insert(spuInfoEntity);
    }

    @Override
    public PageUtils queryPageByCondition(Map<String, Object> params) {
        LambdaQueryWrapper<SpuInfoEntity> spuInfoEntityQueryWrapper = new LambdaQueryWrapper<>();
        String key = (String) params.get("key");
        if (StringUtils.hasText(key)) {
            spuInfoEntityQueryWrapper.and((w) -> w.eq(SpuInfoEntity::getId, key)
                    .or()
                    .like(SpuInfoEntity::getSpuName, key));
        }
        String brandId = (String) params.get("brandId");
        if (StringUtils.hasText(brandId)) {
            spuInfoEntityQueryWrapper.and((w) -> w.eq(SpuInfoEntity::getBrandId, brandId));
        }
        String status = (String) params.get("status");
        if (StringUtils.hasText(status)) {
            spuInfoEntityQueryWrapper.and((w) -> w.eq(SpuInfoEntity::getPublishStatus, status));
        }
        String catelogId = (String) params.get("catelogId");
        if (StringUtils.hasText(catelogId)) {
            spuInfoEntityQueryWrapper.and((w) -> w.eq(SpuInfoEntity::getCatalogId, catelogId));
        }
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                spuInfoEntityQueryWrapper
        );
        return new PageUtils(page);
    }

    /**
     * 商品上架
     *
     * @param spuId
     */
    @Override
    public void up(Long spuId) {
        Long l = spuInfoDao.selectCount(
                new LambdaQueryWrapper<SpuInfoEntity>()
                        .eq(SpuInfoEntity::getId, spuId)
                        .ne(SpuInfoEntity::getPublishStatus, ProductConstant.StatusEnum.SPU_UP.getCode())
        );
        if(l==0){
            return;
        }
        List<SkuInfoEntity> skus = skuInfoDao.selectList(
                new LambdaQueryWrapper<SkuInfoEntity>()
                        .eq(SkuInfoEntity::getSpuId, spuId)
        );
        //TODO 查询属性
        List<ProductAttrValueEntity> productAttrValueEntities = productAttrValueService.baseAttrListforspu(spuId);
        List<Long> AttrIds = productAttrValueEntities.stream().map(ProductAttrValueEntity::getAttrId).collect(Collectors.toList());
        List<AttrEntity> entities = attrDao.selectList(new LambdaQueryWrapper<AttrEntity>()
                .eq(AttrEntity::getSearchType, 1)
                .in(AttrEntity::getAttrId, AttrIds));
        Set<Long> ids = entities.stream().map(AttrEntity::getAttrId).collect(Collectors.toSet());
        ArrayList<SkuEsmodel.Attrs> attrs = new ArrayList<>();
        productAttrValueEntities.forEach(item -> {
            if (ids.contains(item.getAttrId())) {
                SkuEsmodel.Attrs attr = new SkuEsmodel.Attrs();
                BeanUtils.copyProperties(item, attr);
                attrs.add(attr);
            }
        });
        //TODO 远程查看是否有库存
        List<Long> skuIds = skus.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList());
        Map<Long, Integer> SkuHasStockTos = null;
        try {
            R skusHasStock = wareFeifnService.getSkusHasStock(skuIds);
            List<SkuHasStockTo> data = R.toListPoJo(skusHasStock.get("data"), SkuHasStockTo.class);
            SkuHasStockTos = data.stream().collect(Collectors.toMap(SkuHasStockTo::getSkuId, SkuHasStockTo::getStock));
        } catch (RuntimeException e) {
            log.error("远程调用库存服务异常{}", e);
        }


        Map<Long, Integer> finalSkuHasStockTos = SkuHasStockTos;
        List<SkuEsmodel> upProducts = skus.stream().map(sku -> {
            SkuEsmodel skuEsmodel = new SkuEsmodel();
            BeanUtils.copyProperties(sku, skuEsmodel);
            skuEsmodel.setSkuPrice(sku.getPrice());
            skuEsmodel.setSkuImg(sku.getSkuDefaultImg());
            //TODO 加入商品库存
            try {
                skuEsmodel.setHasStock(finalSkuHasStockTos.get(sku.getSkuId()) > 0);
            } catch (NullPointerException e) {
                log.warn("没有库存");
                skuEsmodel.setHasStock(false);
            }
            //TODO 热度评分
            skuEsmodel.setHotScore(0L);
            //TODO 查询品牌和分类名字的信息
            BrandEntity brandEntity = brandDao.selectById(sku.getBrandId());
            skuEsmodel.setBrandName(brandEntity.getName());
            skuEsmodel.setBrandImg(brandEntity.getName());
            CategoryEntity categoryEntity = categoryDao.selectById(sku.getCatalogId());
            skuEsmodel.setCatalogName(categoryEntity.getName());
            //TODO 商品Attr属性
            skuEsmodel.setAttrs(attrs);
            return skuEsmodel;
        }).collect(Collectors.toList());
        R r = searchFenifnService.productStatusUp(upProducts);
        if (r.getCode() == 0) {
            //远程调用成功
            baseMapper.update(
                    new LambdaUpdateWrapper<SpuInfoEntity>().set(SpuInfoEntity::getPublishStatus, ProductConstant.StatusEnum.SPU_UP.getCode())
                            .eq(SpuInfoEntity::getId, spuId)
                            .set(SpuInfoEntity::getUpdateTime, new Date())
                            .set(SpuInfoEntity::getPublishStatus, ProductConstant.StatusEnum.SPU_UP.getCode())
            );
        } else {
            //TODO 重复问题
        }

    }

    @Override
    public SpuInfoEntity getSpuInfoBySkuId(Long skuId) {
        SkuInfoEntity byId = skuInfoService.getById(skuId);
        if (byId != null) {
            return this.getById(byId.getSpuId());
        }
        return null;
    }

}